#include "fluffy.h"

#include <QList>
#include <QMap>
#include <QIODevice>

#include "circle.h"
#include "path.h"
#include "rectangle.h"
#include "textline.h"

TagsContainer FluffyImage::tags = TagsContainer();

FluffyImage::FluffyImage(unsigned int width,unsigned int height)
{
    init(width,height);
}

FluffyImage::FluffyImage()
{
    init(0, 0);
}

FluffyImage::FluffyImage(QString fileName)
{
    loadFromXml(fileName);
}

FluffyImage::FluffyImage(const QDomElement &node)
{
    loadFromNode(node);
}

FluffyImage::~FluffyImage()
{
    qDeleteAll(objects);
}

void FluffyImage::init(unsigned int width,unsigned int height)
{
    this->width = width;
    this->height = height;
}

void FluffyImage::draw(QPaintDevice *device, qreal scale)
{
    foreach(DrawObject* draw, this->objects)
    {
        draw->draw(device, scale);
    }
}

void FluffyImage::saveToXml(QString fileName)
{
    QDomDocument doc(fileName);
    doc.appendChild(saveToNode(doc));

    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly))
    {
        QTextStream(&file) << doc.toString();
        file.close();
    }
}

void FluffyImage::loadFromXml(QString fileName)
{
    QDomDocument domDoc;
    QFile file(fileName);

    if(file.open(QIODevice::ReadOnly))
    {
       try
       {
           if(domDoc.setContent(&file))
           {
              QDomElement domElement = domDoc.documentElement();
              this->loadFromNode(domElement);
           }

           file.close();
       }
       catch(QXmlParseException& exception)
       {
           throw ImageLoadException(QObject::tr("Error load from file: ") + fileName);
       }
       catch(ImageLoadException)
       {
           throw;
       }
    }
    else throw ImageLoadException(QObject::tr("Error load from file: ") + fileName);
}

unsigned int FluffyImage::getWidth()
{
    return width;
}

void FluffyImage::setWidth(unsigned int width)
{
    this->width = width;
}

unsigned int FluffyImage::getHeight()
{
    return height;
}

void FluffyImage::setHeight(unsigned int height)
{
    this->height = height;
}

void FluffyImage::loadFromNode(const QDomElement &node)
{
    this->width = node.attribute("width","").toInt();
    this->height = node.attribute("height","").toInt();

    QDomNode domNode = node.firstChild();
    while(!domNode.isNull())
    {
        if(domNode.isElement())
        {
            QDomElement domElement = domNode.toElement();
            if(!domElement.isNull())
            {
                DrawObject* obj;
                //Определяем тип элемента
                FluffyItemType fiType;
                if (this->tags.itemTags().contains(domElement.tagName()))
                    fiType = this->tags.itemTags()[domElement.tagName()];
                else
                    fiType = ItemType_None;
                // Создаём нужный класс
                switch (fiType)
                {
                    case ItemType_Path:
                        obj = new Path();
                        break;
                    case ItemType_Rectangle:
                        obj = new Rectangle();
                        break;
                    case ItemType_Circle:
                        obj = new Circle();
                        break;
                    case ItemType_Text:
                        obj = new TextLine();
                        break;
                    case ItemType_None:
                        throw ImageLoadException(QObject::tr("Not supported item type"));
                        break;
                }
                obj->loadFromNode(domElement);
                this->objects.append(obj);
            }
        }
        domNode = domNode.nextSibling();
   }
}

QDomElement FluffyImage::saveToNode(QDomDocument &domDoc)
{
    QDomElement rootElement = domDoc.createElement("svg");
    rootElement.setAttribute("width",this->width);
    rootElement.setAttribute("height",this->height);

    foreach (DrawObject* item, objects)
        rootElement.appendChild(item->saveToNode(domDoc));
    return rootElement;
}
